package com.github.dabai.aggregation;

import java.beans.PropertyDescriptor;
import java.util.Map;

import org.apache.commons.beanutils.PropertyUtils;

public interface IAggregationConvert<I extends IAggregatingInput,O extends IAggregatingOut> {
	O convert(GroupByKey key, Map<String, AggregationField<I>> aggregations,
			Map<String, AggregationPostField<I>> posts, Class<O> outClass) throws Exception;

	class CommonAggregationConvert<I extends IAggregatingInput,O extends IAggregatingOut>implements IAggregationConvert<I,O> {
		@Override
		public O convert(GroupByKey key, Map<String, AggregationField<I>> aggregations,
				Map<String, AggregationPostField<I>> posts, Class<O> outClass) throws Exception {
			O entity = outClass.newInstance();
			PropertyDescriptor propertyDescriptors[] = PropertyUtils.getPropertyDescriptors(outClass);
			for (PropertyDescriptor pd : propertyDescriptors) {
				String name = pd.getName();
				try {
					Object value = null;
					int count = 0;
					if (aggregations.containsKey(name)) {
						AggregationField<I> af = aggregations.get(name);
						if (af != null) {
							value = af.getResult();
							count++;
						}
					}
					if (posts.containsKey(name)) {
						AggregationPostField<I> af = posts.get(name);
						if (af != null) {
							value = af.getResult();
							count++;
						}
					}
					if (key.containsMappingName(name)) {
						value = key.getByMappingName(name);
						count++;
					}
					if (count == 1 && value != null) {
						pd.getWriteMethod().invoke(entity, value);
					}
					if (count > 1) {
						throw new RuntimeException(
								outClass.getName() + " property " + name + " set value repeat error");
					}
				} catch (Exception e) {
					throw e;
				}
			}
			return entity;
		}
	}
}
